package com.joysuch.wwyt.list.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.joysuch.wwyt.bp.entity.BpDepart;
import com.joysuch.wwyt.bp.repository.BpDepartDao;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.security.ShiroUser;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.list.bean.*;
import com.joysuch.wwyt.list.entity.BpListBiz;
import com.joysuch.wwyt.list.entity.BpListBizWork;
import com.joysuch.wwyt.list.enums.ListBizState;
import com.joysuch.wwyt.list.mapper.BpListBizMapper;
import com.joysuch.wwyt.list.mapper.BpListBizWorkMapper;
import com.joysuch.wwyt.list.mapper.BpListTypeMapper;
import com.joysuch.wwyt.list.service.BpListBizService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xiaoying
 * @since 2021-05-17
 */
@Slf4j
@Service
public class BpListBizServiceImpl extends ServiceImpl<BpListBizMapper, BpListBiz> implements BpListBizService {


    @Autowired
    private BpListBizMapper bpListBizMapper;

    @Autowired
    private BpListTypeMapper bpListTypeMapper;

    @Autowired
    private BaseUserDao baseUserDao;

    @Autowired
    private BpListBizWorkMapper bpListBizWorkMapper;

    @Autowired
    private BpDepartDao bpDepartDao;

    @Override
    public ResultBean save(BpListBizEditBean bean) {

        BpListBiz bpListBiz = null;
        if (bean.getPublishTime() != null && bean.getListCreateTime() != null) {
            if (bean.getPublishTime().before(bean.getListCreateTime())) {
                return ResultBean.wrapErrorResultDefault("清单发布时间不能早于清单创建时间");
            }
        }
        if (StringUtils.isNotBlank(bean.getAttachments())) {
            JSONArray attachments = JSONObject.parseArray(bean.getAttachments());
            if (attachments.size() > 5) {
                return ResultBean.wrapErrorResultDefault("附件数量不能超过5个");
            }
        }
        //是否新增
        boolean isNew = false;
        if (bean.getId() == null) {
            isNew = true;
            bpListBiz = new BpListBiz();
        } else {
            bpListBiz = getById(bean.getId());
        }
        BeanUtils.copyProperties(bean, bpListBiz);
        // 编号与名称 唯一校验
        if (checkDuplicateCode(bean, isNew)) {
            return ResultBean.wrapErrorResultDefault("清单编号已存在，编号不能重复。");
        }
        if (checkDuplicateName(bean, isNew)) {
            return ResultBean.wrapErrorResultDefault("清单名称已存在，同类型下的名称不能重复。");
        }

        if (isNew) {
            bpListBizMapper.insert(bpListBiz);
        } else {
            bpListBiz.setUpdateTime(new Date());
            bpListBizMapper.updateById(bpListBiz);
        }
        return ResultBean.success(bpListBiz);
    }

    /**
     * 清单编号唯一校验
     *
     * @param bean
     * @param isNew
     * @return
     */
    private boolean checkDuplicateCode(BpListBizEditBean bean, boolean isNew) {
        LambdaQueryWrapper<BpListBiz> lqw = new LambdaQueryWrapper<>();
        lqw.eq(BpListBiz::getListCode, bean.getListCode());
        lqw.eq(BpListBiz::getDeleteFlag, "0");
        lqw.eq(BpListBiz::getTenentId, Context.getCurrentTenantId());
        lqw.likeRight(BpListBiz::getOrgCode, Context.getCompanyCode());
        List<BpListBiz> list = bpListBizMapper.selectList(lqw);
        if (list != null && list.size() > 0) {
            if (isNew) {
                return true;
            } else if (list.size() == 1 && !list.get(0).getId().equals(bean.getId())) {
                return true;
            } else if (list.size() > 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * 清单名称在同一类型下唯一校验
     *
     * @param bean
     * @param isNew
     * @return
     */
    private boolean checkDuplicateName(BpListBizEditBean bean, boolean isNew) {
        LambdaQueryWrapper<BpListBiz> lqw = new LambdaQueryWrapper<>();
        lqw.eq(BpListBiz::getListName, bean.getListName());
        lqw.eq(BpListBiz::getTypeId, bean.getTypeId());
        lqw.eq(BpListBiz::getDeleteFlag, "0");
        lqw.eq(BpListBiz::getTenentId, Context.getCurrentTenantId());
        lqw.likeRight(BpListBiz::getOrgCode, Context.getCompanyCode());

        List<BpListBiz> list = bpListBizMapper.selectList(lqw);
        if (list != null && list.size() > 0) {
            if (isNew) {
                return true;
            } else if (list.size() == 1 && !list.get(0).getId().equals(bean.getId())) {
                return true;
            } else if (list.size() > 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * 清单工作名称唯一校验
     *
     * @param bean
     * @param isNew
     * @return
     */
    private boolean checkWorkDuplicateName(BpListBizUploadWorkEditBean bean, boolean isNew) {
        LambdaQueryWrapper<BpListBizWork> lqw = new LambdaQueryWrapper<>();
        lqw.eq(BpListBizWork::getWorkName, bean.getWorkName());
        lqw.eq(BpListBizWork::getDeleteFlag, "0");
        lqw.eq(BpListBizWork::getTenentId, Context.getCurrentTenantId());
        lqw.likeRight(BpListBizWork::getOrgCode, Context.getCompanyCode());

        List<BpListBizWork> list = bpListBizWorkMapper.selectList(lqw);
        if (list != null && list.size() > 0) {
            if (isNew) {
                return true;
            } else if (list.size() == 1 && !list.get(0).getId().equals(bean.getId())) {
                return true;
            } else if (list.size() > 1) {
                return true;
            }
        }
        return false;
    }

    @Override
    public BpListBizDetailBean getDetailById(Long id) {
        BpListBiz entity = getById(id);
        BpListBizDetailBean bean = new BpListBizDetailBean();
        if (entity != null) {
            BeanUtils.copyProperties(entity, bean);
            String name = null;
            if (entity.getCreateBy() != null) {
                name = baseUserDao.getRealNameById(entity.getCreateBy());
                if (name != null) {
                    bean.setCreateByUserName(name);
                }
            }
            if (entity.getUpdateBy() != null) {
                name = baseUserDao.getRealNameById(entity.getUpdateBy());
                if (name != null) {
                    bean.setUpdateByUserName(name);
                }
            }
            if (entity.getState() != null) {
                bean.setStateName(ListBizState.findNameByCode(entity.getState()));
            }
        }

        return bean;
    }

    @Override
    public int deleteById(Long id) {
        return bpListBizMapper.deleteById(id);
    }

    @Override
    public IPage<BpListBizListBean> pageAll(Page<BpListBizListBean> page, BpListBizQueryBean queryBean) {
        BpListBizParamBean paramBean = new BpListBizParamBean();
        BeanUtils.copyProperties(queryBean, paramBean);
        convertDate(paramBean);
        //查询当前类型与所有子类型
        if (queryBean.getTypeId() != null) {
            List<Long> typeList = findChildIdsByParentId(queryBean.getTypeId());
            paramBean.setTypeIds(typeList);
            typeList.add(queryBean.getTypeId());
        }
        paramBean.setOrgCode(Context.getCompanyCode());
        paramBean.setTenentId(Context.getCurrentTenantId());
        return convert(bpListBizMapper.pageAll(page, paramBean));
    }

    private void convertDate(BpListBizParamBean paramBean) {
        if (paramBean.getStartDate() != null) {
            paramBean.setStartDate(DateUtil.beginOfDay(paramBean.getStartDate()));
        }
        if (paramBean.getEndDate() != null) {
            paramBean.setEndDate(DateUtil.endOfDay(paramBean.getEndDate()));
        }
    }

    private void convertDate2(BpListBizWorkParamBean paramBean) {
        if (paramBean.getStartDate() != null) {
            paramBean.setStartDate(DateUtil.beginOfDay(paramBean.getStartDate()));
        }
        if (paramBean.getEndDate() != null) {
            paramBean.setEndDate(DateUtil.endOfDay(paramBean.getEndDate()));
        }
    }

    private IPage<BpListBizListBean> convert(IPage<BpListBizListBean> pageData) {
        if (pageData.getTotal() > 0) {
            List<BpListBizListBean> list = new ArrayList<>();
            pageData.getRecords().stream().forEach(item -> {
                BpListBizListBean bean = new BpListBizListBean();
                BeanUtils.copyProperties(item, bean);
                String name = null;
                if (item.getCreateBy() != null) {
                    name = baseUserDao.getRealNameById(item.getCreateBy());
                    if (name != null) {
                        bean.setCreateByUserName(name);
                    }
                }
                if (item.getUpdateBy() != null) {
                    name = baseUserDao.getRealNameById(item.getUpdateBy());
                    if (name != null) {
                        bean.setUpdateByUserName(name);
                    }
                }
                if (item.getState() != null) {
                    bean.setStateName(ListBizState.findNameByCode(item.getState()));
                }
                list.add(bean);
            });
            pageData.setRecords(list);
        }
        return pageData;
    }


    @Override
    public IPage<BpListBizListBean> myPage(Page<BpListBizListBean> page, BpListBizQueryBean queryBean) {
        BpListBizParamBean paramBean = new BpListBizParamBean();
        BeanUtils.copyProperties(queryBean, paramBean);
        paramBean.setCurrentJob(Context.getJobId());
        paramBean.setCurrentDepart(Context.getCurrentDepartId());
        paramBean.setCurrentId(Context.getCurrentUserId());
        convertDate(paramBean);
        //查询当前类型与所有子类型
        if (queryBean.getTypeId() != null) {
            List<Long> typeList = findChildIdsByParentId(queryBean.getTypeId());
            paramBean.setTypeIds(typeList);
            typeList.add(queryBean.getTypeId());
        }
        return convert(bpListBizMapper.myPage(page, paramBean));
    }

    @Override
    public ResultBean saveUploadWork(BpListBizUploadWorkEditBean bean) {
        BpListBizWork bpListBizWork = null;
        if (StringUtils.isNotBlank(bean.getAttachments())) {
            JSONArray attachments = JSONObject.parseArray(bean.getAttachments());
            if (attachments.size() > 5) {
                return ResultBean.wrapErrorResultDefault("附件数量不能超过5个");
            }
        }
        //是否新增
        boolean isNew = false;
        if (bean.getId() == null) {
            isNew = true;
            bpListBizWork = new BpListBizWork();
        } else {
            bpListBizWork = bpListBizWorkMapper.selectById(bean.getId());
        }
        BeanUtils.copyProperties(bean, bpListBizWork);
        //名称 唯一校验
        if (checkWorkDuplicateName(bean, isNew)) {
            return ResultBean.wrapErrorResultDefault("工作名称已存在");
        }

        if (isNew) {
            bpListBizWorkMapper.insert(bpListBizWork);
        } else {
            bpListBizWork.setUpdateTime(new Date());
            bpListBizWorkMapper.updateById(bpListBizWork);
        }
        return ResultBean.success(bpListBizWork);
    }

    @Override
    public IPage<BpListBizUploadWorkBean> workPageAll(Page<BpListBizUploadWorkBean> page, BpListBizWorkQueryBean queryBean) {
        BpListBizWorkParamBean paramBean = new BpListBizWorkParamBean();
        BeanUtils.copyProperties(queryBean, paramBean);
        convertDate2(paramBean);
        paramBean.setOrgCode(Context.getCompanyCode());
        paramBean.setTenentId(Context.getCurrentTenantId());
        IPage<BpListBizUploadWorkBean> list = null;
        ShiroUser currentUser = Context.getCurrentUser();
        List<Long> userIds = Lists.newArrayList();
        Optional<BpDepart> opt = bpDepartDao.findById(currentUser.getDepartId());
        if (opt.isPresent()) {
            BpDepart bpDepart = opt.get();
            //如果当前登录人员所在部门没有部门负责人，则只能看到每个人员自己的清单工作列表
            if (org.springframework.util.StringUtils.isEmpty(bpDepart.getChiefId())) {
                userIds.add(currentUser.getRealUserId());
            } else {
                if (currentUser.getRealUserId().equals(bpDepart.getChiefId())) {
                    //是部门负责人可查看部门下所有人员工作列表
                    //当前部门下所有员工ID
                    List<Long> baseUserIds = baseUserDao.findIdByDepartId(currentUser.getDepartId());
                    userIds.addAll(baseUserIds);
                } else {
                    //不是负责人只能查看自己的工作列表
                    userIds.add(currentUser.getRealUserId());
                }
            }
        }
        paramBean.setCreateByIds(userIds);
        list = bpListBizWorkMapper.workPageAll(page, paramBean);
        list.getRecords().forEach(w -> {
            if (w.getState() != null) {
                if (w.getState() == 0) {
                    w.setStateName("未完成");
                } else {
                    w.setStateName("完成");
                }
            }
        });
        return list;
    }

    @Override
    public BpListBizWorkDetailBean getDetailByWorkId(Long id) {
        BpListBizWork entity = bpListBizWorkMapper.selectById(id);
        BpListBizWorkDetailBean bean = new BpListBizWorkDetailBean();
        if (entity != null) {
            BeanUtils.copyProperties(entity, bean);
            String name = null;
            if (entity.getCreateBy() != null) {
                name = baseUserDao.getRealNameById(entity.getCreateBy());
                if (name != null) {
                    bean.setCreateByName(name);
                }
            }
            if (entity.getUpdateBy() != null) {
                name = baseUserDao.getRealNameById(entity.getUpdateBy());
                if (name != null) {
                    bean.setUpdateByName(name);
                }
            }
            if (entity.getState() != null) {
                if (entity.getState() == 0) {
                    bean.setStateName("未完成");
                } else {
                    bean.setStateName("完成");
                }
            }
            if (entity.getListId() != null) {
                BpListBiz bpListBiz = getById(entity.getListId());
                if (bpListBiz != null) {
                    bean.setListCode(bpListBiz.getListCode());
                    bean.setListName(bpListBiz.getListName());
                }
            }
        }

        return bean;
    }

    @Override
    public List<BpListBizUploadWorkBean> findPage(BpListBizWorkQueryBean queryBean) {
        BpListBizWorkParamBean paramBean = new BpListBizWorkParamBean();
        BeanUtils.copyProperties(queryBean, paramBean);
        paramBean.setOrgCode(Context.getCompanyCode());
        paramBean.setTenentId(Context.getCurrentTenantId());
        List<BpListBizUploadWorkBean> list = null;
        ShiroUser currentUser = Context.getCurrentUser();
        List<Long> userIds = Lists.newArrayList();
        Optional<BpDepart> opt = bpDepartDao.findById(currentUser.getDepartId());
        if (opt.isPresent()) {
            BpDepart bpDepart = opt.get();
            //如果当前登录人员所在部门没有部门负责人，则只能看到每个人员自己的清单工作列表
            if (org.springframework.util.StringUtils.isEmpty(bpDepart.getChiefId())) {
                userIds.add(currentUser.getRealUserId());
            } else {
                if (currentUser.getRealUserId().equals(bpDepart.getChiefId())) {
                    //是部门负责人可查看部门下所有人员工作列表
                    //当前部门下所有员工ID
                    List<Long> baseUserIds = baseUserDao.findIdByDepartId(currentUser.getDepartId());
                    userIds.addAll(baseUserIds);
                } else {
                    //不是负责人只能查看自己的工作列表
                    userIds.add(currentUser.getRealUserId());
                }
            }
        }
        paramBean.setCreateByIds(userIds);
        list = bpListBizWorkMapper.findPage(paramBean);
        list.forEach(w -> {
            if (w.getState() != null) {
                if (w.getState() == 0) {
                    w.setStateName("未完成");
                } else {
                    w.setStateName("完成");
                }
            }
        });
        return list;
    }

    private List getChildrensTypeList(Long parentId, List<Long> childrenList) {
        List<Long> typeList = bpListTypeMapper.findIdsByParentId(parentId);
        if (typeList != null && typeList.size() > 0) {
            childrenList.addAll(typeList);
            for (Long id : typeList) {
                getChildrensTypeList(id, childrenList);
            }
        }
        return childrenList;
    }


    private List<Long> findChildIdsByParentId(Long parentId) {
        return getChildrensTypeList(parentId, new ArrayList<>());
    }


}
